/*
 *  RIBuildIndexSVPR.java
 *
 */

package at.ofai.gate.riplugin2;


import gate.*;
import gate.creole.*;
import gate.creole.metadata.*;
import gate.util.GateRuntimeException;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import pitt.search.semanticvectors.*;
import pitt.search.semanticvectors.vectors.VectorType;

// document names:
// gatedocid.sectionid where gatedocid is gatedocnr:gatedocname and
// sectionid is annotationnr:annotationname:fromoffset:tooffset


/** 
 * This PR must be run in a controller, not a corpus controller.
 */
@CreoleResource(name = "RIBuildIndexSVPositionalPR2",
    icon = "riindex",
    //helpURL = "http://gate.ac.uk/userguide/sec:somechapter:sometopic:somepos",
    comment = "Create a SV Positional Random Indexing Datastructure")
public class RIBuildIndexSVPositionalPR
  extends RIBuildIndexSVPR
  implements ProcessingResource
{

  @CreoleParameter(comment = "Window radius/neighboring terms", defaultValue="10")
  @Optional
  @RunTime
  public void setWindowRadius(Integer i) {
    this.windowRadius = i;
  }
  public Integer getWindowRadius() {
    return this.windowRadius;
  }
  private Integer windowRadius = 10;


  @CreoleParameter(comment = "The SemanticVectors Positional Index LR to fill")
  @RunTime
  public void setIndexSVLR(RIIndexSVLR index) {
    this.indexSVLR = index;
  }

  public RIIndexSVLR getIndexSVLR() {
    return this.indexSVLR;
  }
  private RIIndexSVLR indexSVLR = null;


  public static final Logger logger =
    Logger.getLogger(RIBuildIndexSVPositionalPR.class.getName());


  /**
   * Initialize this resource: check parameters 
   *
   * @return
   * @throws ResourceInstantiationException
   */
  @Override
  public Resource init() throws ResourceInstantiationException {
    super.init();
    if(getWindowRadius() == null || getWindowRadius() < 1) {
      throw new ResourceInstantiationException("Window radius must be at least 1");
    }
    return this;
  }

  /**
   * Run the index creation ....
   * 
   * @throws ExecutionException
   */
  @Override
  public void execute() throws ExecutionException {
    // check the directory URL and create the luceneIndexDir file
    luceneIndexDir = indexLuceneLR.getLuceneIndexDir();
    svTermIndex = indexSVLR.getSVTermIndex();
    svDocumentIndex = indexSVLR.getSVDocumentIndex();
    // TODO: check that the SV index dir exists
    // TODO: check that the lucene LR has data
    if(svTermIndex.exists()) {
      FileUtils.deleteQuietly(svTermIndex);
      logger.info("Existing SemanticVectors termvectors.bin file deleted");
    }
    if(svDocumentIndex.exists()) {
      FileUtils.deleteQuietly(svDocumentIndex);
      logger.info("Existing SemanticVectors docvectors.bin file deleted");
    }
    // create the SemanticVectors index files
    // For now the following parameters are fixed
    int dimensions = getVectorDimensions();
    int seedlength = getSeedDimensions();
    int minfrequency = getMinTermFrequency();
    int windowsize = getWindowRadius();
    int maxnonalphabetchars = -1;
    String[] contentsfields = {"contents"};
    VectorStoreRAM initialdocvectors = null;
    TermTermVectorsFromLucene vecStore;
    //System.out.println("Creating elemental document vectors ...");
    try {
      Flags.dimension = dimensions;
      Flags.vectortype = "real";
      vecStore =
        new TermTermVectorsFromLucene(
          luceneIndexDir.getCanonicalPath(),
          VectorType.REAL,
          dimensions,
          seedlength,
          minfrequency,
          Integer.MAX_VALUE,
          maxnonalphabetchars,
          windowsize,
          "permutation",
          null, 
          contentsfields);
    } catch (Exception ex) {
      throw new GateRuntimeException("Exception elemental doc vectors: ",ex);
    }
    VectorStoreWriter vecWriter = new VectorStoreWriter();
    try {
      //System.out.println("Writing term vectors to " + svTermIndex.getAbsolutePath());
      VectorStoreWriter.writeVectors(svTermIndex.getCanonicalPath(), vecStore);
    } catch (Exception ex) {
      throw new GateRuntimeException("Exception writing doc or term vectors",ex);
    }    IncrementalDocVectors docVectors = null;
    try {
      //System.out.println("Creating document vectors ...");
        IncrementalDocVectors.createIncrementalDocVectors(
              vecStore, 
              luceneIndexDir.getCanonicalPath(),
              contentsfields, 
              svDocumentIndex.getCanonicalPath());
    } catch (IOException ex) {
      throw new GateRuntimeException("Exception creating doc vectors store",ex);
    }
  }


  
} // class RIBuildSVPR
